מדריך ליצירת טופס לשליחת אימייל מהאתר עם הסברים ודוגמאות קוד
+ בונוס הגנה על תיבת המייל מפני ספאם והודעות חוזרות.
נעבור יחד שלב שלב ונתמקד בבניית טופס יצירת קשר ושליחת אימייל ב-php
1. בניית טופס
2. קבלה ואימות נתונים
3. איך לשלוח אימייל
4. שליחת הטופס באימייל
5. הגנה על תיבת הדואר
טופס יצירת קשר
השלב הראשון שנדרש לבניית טופס יצירת קשר זהו הטופס עצמו.
בסיס לטופס יצירת קשר שתוכלו לעצב מאוחר יותר יראה כך:
<form method="post">
Subject: <input type="text" name="subject"> <br>
Content: <br> <textarea name="text" rows="10" cols="25"></textarea> <br>
<input type="submit" name="contact" value="Send us a message">
</form>
Subject: <input type="text" name="subject"> <br>
Content: <br> <textarea name="text" rows="10" cols="25"></textarea> <br>
<input type="submit" name="contact" value="Send us a message">
</form>
2. יש קשר עם השרת?
בשרת יהיה עלינו לבדוק שהטופס הגיע, הגיע לא ריק ולא כתבו לנו הרבה רווחים במקום טקסט.
<?php
if( isset($_POST['contact'], $_POST['subject'], $_POST['text']) )
{
$subject = trim ($_POST['subject']);
$text = trim ($_POST['text']);
if(strlen($subject) < 3 || strlen($text) < 3) echo 'Text is too short';
}
?>
<form method="post">
Subject: <input type="text" name="subject"> <br>
Content: <br> <textarea name="text" rows="10" cols="25"></textarea> <br>
<input type="submit" name="contact" value="Send us a message">
</form>
if( isset($_POST['contact'], $_POST['subject'], $_POST['text']) )
{
$subject = trim ($_POST['subject']);
$text = trim ($_POST['text']);
if(strlen($subject) < 3 || strlen($text) < 3) echo 'Text is too short';
}
?>
<form method="post">
Subject: <input type="text" name="subject"> <br>
Content: <br> <textarea name="text" rows="10" cols="25"></textarea> <br>
<input type="submit" name="contact" value="Send us a message">
</form>
הפונקציה isset בודקת האם המשתנה מוגדר.
סוד קטן שלא כולם יודעים הוא ש-isset מסוגלת לבדוק בבת אחת כמה משתנים.
במידה והמשתמש לא שלח את הטופס או שלח טופס אחר — אחד מהשדות הללו יהיה לא מוגדר ולכן isset תחזיר false
לאחר שווידאנו שהטופס אכן התקבל בשרת - נבדוק את תוכנו.
הפונקציה trim גוזרת את כל הרווחים מתחילת וסוף השורה, לכן הודעה שהתוכן שלה הוא אך ורק רווחים תהיה הודעה פסולה. לאחר גזירת הרווחים בתחילתם וסופם של נושא ותוכן ההודעה נבדוק את אורכם.
המשתמש המיסכן
כמה פעמים קרה לכם שכתבתם משהו ארוך, לחצתם שמור/שלח, קיבלתם הודעת שגיאה וחזרתם לעמוד עם טופס ריק כדי להקליד הכל שוב פעם?
כדי שזה לא יקרה יהיה עלינו, במקרה של שגיאה, להציג למשתמש את הנתונים שלו שוב באופן הבא:
<?php
if( isset($_POST['contact'], $_POST['subject'], $_POST['text']) )
{
$subject = trim ($_POST['subject']);
$text = trim ($_POST['text']);
if(strlen($subject) < 3 || strlen($text) < 3) echo 'Text is too short';
}
?>
<form method="post">
Subject: <input type="text" name="subject" value="<?php
if(isset($_POST['subject'])) echo htmlspecialchars($_POST['subject']);
?>"> <br>
Content: <br> <textarea name="text" rows="10" cols="25"><?php
if(isset($_POST['text'])) echo htmlspecialchars($_POST['text']);
?></textarea> <br>
<input type="submit" name="contact" value="Send us a message">
</form>
if( isset($_POST['contact'], $_POST['subject'], $_POST['text']) )
{
$subject = trim ($_POST['subject']);
$text = trim ($_POST['text']);
if(strlen($subject) < 3 || strlen($text) < 3) echo 'Text is too short';
}
?>
<form method="post">
Subject: <input type="text" name="subject" value="<?php
if(isset($_POST['subject'])) echo htmlspecialchars($_POST['subject']);
?>"> <br>
Content: <br> <textarea name="text" rows="10" cols="25"><?php
if(isset($_POST['text'])) echo htmlspecialchars($_POST['text']);
?></textarea> <br>
<input type="submit" name="contact" value="Send us a message">
</form>
שימו לב שהקוד הזה בודק האם מוגדרים המשתנים (כלומר האם המשתמש הרגע שלח את הטופס). במידה וכן - נציג לו את תוכן הנושא וההודעה בשדות המתאימים.
3. שליחת אימייל
שליחת אימייל באמצעות php הוא עניין של שורה אחת בלבד
באמצעות פונקציית שליחת mail()
בואו נראה קוד פשוט לשליחת אימייל:
הקוד הזה שולח אימייל עם הנושא Subject והתוכן Message לכתובת הנ"ל.
שימו לב, wamp, xamp וכל שרת ביתי אחר אינו תומך בשליחת אימייל
לכן לא ניתן לשלוח אימייל מהשרת הביתי שלכם.
במידה ויש לכם חברת אחסון כלשהי נסו לשחק עם הקוד הזה שם.
פונקציית mail
אימייל מורכב משני חלקים: תוכן (נושא וטקסט) וכותרים (headers)
בדיוק כמו תקשורת בין דפדפן לשרת. בכותרים הללו ניתן להגדיר הגדרות או להוסיף פרטים לאימייל שלנו. לדוגמה, ניתן לשלוח באימייל html במקום טקסט רגיל אם נרשום זאת בכותרים.
<?php
$message = '
<html>
<head><title>test</title></head>
<body><b>hi there</b></body>
</html>
';
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
mail("[email protected]", "Subject", $message, $headers);
$message = '
<html>
<head><title>test</title></head>
<body><b>hi there</b></body>
</html>
';
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
mail("[email protected]", "Subject", $message, $headers);
שני הכותרים מופרדים במעבר שורה \r\n (ראו עוד על סימנים מיוחדים) ובעזרתם תוכנת קריאת האימיילים תדע להציג את ההודעה שלנו.
במידה ותרצו לשלוח אימייל בעברית תוכלו לשלוח כותר עם קידוד במידה ויהיו בעיות תצוגה.
חשוב לדעת: פונקציית mail מעבירה את ההודעה לתוכנה אחרת, הנקראת SMTP, שאחראית לשליחה בפועל. במחשב הביתי שלכם כנראה אינה מותקנת תכנה כזו ולכן אין אפשרות לשלוח אימייל מהמחשב הביתי.
לכן, אם פונקציית mail החזירה true, הדבר אינו אומר שהדואר אכן נשלח, אלה רק שההודעה הועברה בהצלחה לשרת ה-smtp בהצלחה ונשאר לקוות שמשם היא תגיע ליעד ללא שגיאות.
Warning: mail(): "sendmail_from" not set in php.ini or custom "From:" header missing
יכול מאוד להיות שתקבלו את השגיאה הזו.
אימייל, כמו דואר רגיל, חייב להכיל כותר "מאת" (מוען).
במידה והוגדר בקובץ php.ini מוען כלשהו, php תוסיף את הכותר הזה לבד בכל שליחת אימייל. במידה ואינו מוגדר, רצוי להגדיר אותו או להעביר ככותר נפרד לפונקציית mail
$header = 'From: Moshe Levi <[email protected]>';
mail("[email protected]","Subject","Message", $header);
mail("[email protected]","Subject","Message", $header);
ניתן להזין כל אימייל במוען ולגרום לנמען לחשוב שהאימייל הגיע ממקום אחר.
אך אל תתפטו לשלוח אימיילים זדוניים לכל כיוון. לא משנה מה יהיה כתוב בכותר, לא תהיה שום בעיה לגלות מאיזה שרת בפועל הגיע הדואר ולאתר את השולח האמיתי.
4. חיבור בין הטופס לשליחה
כעת נחבר בין הטופס לשליחה ונקבל את הקוד הבא:
<?php
if( isset($_POST['contact'], $_POST['subject'], $_POST['text']) )
{
$subject = trim ($_POST['subject']);
$text = trim ($_POST['text']);
if(strlen($subject) < 3 || strlen($text) < 3) echo 'Text is too short';
else
{
if(! mail("[email protected]", $subject, $text) ) echo 'Error sending mail';
else echo 'Mail sent successfully.';
}
}
?>
<form method="post">
Subject: <input type="text" name="subject" value="<?php
if(isset($_POST['subject'])) echo htmlspecialchars($_POST['subject']);
?>"> <br>
Content: <br> <textarea name="text" rows="10" cols="25"><?php
if(isset($_POST['text'])) echo htmlspecialchars($_POST['subject']);
?></textarea> <br>
<input type="submit" name="contact" value="Send us a message">
</form>
if( isset($_POST['contact'], $_POST['subject'], $_POST['text']) )
{
$subject = trim ($_POST['subject']);
$text = trim ($_POST['text']);
if(strlen($subject) < 3 || strlen($text) < 3) echo 'Text is too short';
else
{
if(! mail("[email protected]", $subject, $text) ) echo 'Error sending mail';
else echo 'Mail sent successfully.';
}
}
?>
<form method="post">
Subject: <input type="text" name="subject" value="<?php
if(isset($_POST['subject'])) echo htmlspecialchars($_POST['subject']);
?>"> <br>
Content: <br> <textarea name="text" rows="10" cols="25"><?php
if(isset($_POST['text'])) echo htmlspecialchars($_POST['subject']);
?></textarea> <br>
<input type="submit" name="contact" value="Send us a message">
</form>
איך זה עובד
נציב את המשתנים בפונקציית mail ונוודא שהיא מצליחה לבצע את שלה.
אם היא לא מצליחה ומחזירה false — נציג הודעה כי השליחה נכשלה.
5. הגנה מפני ספאם
(החלק הזה אינו חובה לקריאה ועבודה)
יכול מאוד להיות שלמישהו יתחשק להציף את תיבת הדואר שלכם בהודעות.
כדי שזה לא יקרה נציב הגבלה על כמות ההודעות המירבית.
לא יותר מהודעה אחת למשתמש (ip) בדקה ולא יותר מ-20 הודעות ביום.
אפשרות נוספת להגנה היא הצבת תמונת captcha שלא מהווה שום קושי לפיענוח על ידי מכונה ומתרידה את הציבור.
עלינו לשמור נתונים — מי שלח אימייל ומתי שלח אימייל.
הדרך היעילה ביותר תהינה מסד נתונים mysql
ניצור טבלה mail_log עם שני שדות
ip - varchar(15)
time - timestamp
CREATE TABLE IF NOT EXISTS `mail_log` (
`ip` varchar(15) NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
KEY `ip` (`ip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`ip` varchar(15) NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
KEY `ip` (`ip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
עם כל שליחת אימייל יהיה עלינו תחילה לבדוק שלא עברנו את המגבלה,
ולאחר השליחה לרשום בטבלה שהשליחה התבצעה.
<?php
if( isset($_POST['contact'], $_POST['subject'], $_POST['text']) )
{
$subject = trim ($_POST['subject']);
$text = trim ($_POST['text']);
if(strlen($subject) < 3 || strlen($text) < 3) echo 'Text is too short';
else
{
$db = mysql_connect("localhost", "user","password");
mysql_select_db("database", $db);
mysql_query("SET NAMES 'UTF8'", $db);
$ip = mysql_real_escape_string($_SERVER['REMOTE_ADDR']);
$queryR = mysql_query
("
SELECT COUNT(*), UNIX_TIMESTAMP(MAX(`time`))
FROM `mail_log` WHERE `ip`='$ip' AND
`time` > DATE_SUB(NOW(), INTERVAL 1 DAY)
", $db);
$results = mysql_fetch_row($queryR);
if($results[0] > 20 || $results[1]+60 > time()) echo 'SPAAAM!!!!';
elseif(! mail("[email protected]", $subject, $text) )
echo 'Error sending mail';
else
{
mysql_query("INSERT INTO `mail_log` (`ip`,`time`)
VALUES ('$ip', CURRENT_TIMESTAMP())", $db);
echo 'Mail sent successfully.';
}
}
}
?>
<form method="post">
Subject: <input type="text" name="subject" value="<?php
if(isset($_POST['subject'])) echo htmlspecialchars($_POST['subject']);
?>"> <br>
Content: <br> <textarea name="text" rows="10" cols="25"><?php
if(isset($_POST['text'])) echo htmlspecialchars($_POST['subject']);
?></textarea> <br>
<input type="submit" name="contact" value="Send us a message">
</form>
if( isset($_POST['contact'], $_POST['subject'], $_POST['text']) )
{
$subject = trim ($_POST['subject']);
$text = trim ($_POST['text']);
if(strlen($subject) < 3 || strlen($text) < 3) echo 'Text is too short';
else
{
$db = mysql_connect("localhost", "user","password");
mysql_select_db("database", $db);
mysql_query("SET NAMES 'UTF8'", $db);
$ip = mysql_real_escape_string($_SERVER['REMOTE_ADDR']);
$queryR = mysql_query
("
SELECT COUNT(*), UNIX_TIMESTAMP(MAX(`time`))
FROM `mail_log` WHERE `ip`='$ip' AND
`time` > DATE_SUB(NOW(), INTERVAL 1 DAY)
", $db);
$results = mysql_fetch_row($queryR);
if($results[0] > 20 || $results[1]+60 > time()) echo 'SPAAAM!!!!';
elseif(! mail("[email protected]", $subject, $text) )
echo 'Error sending mail';
else
{
mysql_query("INSERT INTO `mail_log` (`ip`,`time`)
VALUES ('$ip', CURRENT_TIMESTAMP())", $db);
echo 'Mail sent successfully.';
}
}
}
?>
<form method="post">
Subject: <input type="text" name="subject" value="<?php
if(isset($_POST['subject'])) echo htmlspecialchars($_POST['subject']);
?>"> <br>
Content: <br> <textarea name="text" rows="10" cols="25"><?php
if(isset($_POST['text'])) echo htmlspecialchars($_POST['subject']);
?></textarea> <br>
<input type="submit" name="contact" value="Send us a message">
</form>
איך זה עובד?
רק במידה והגיע אלינו טופס מלא — נבצע חיבור למסד.
לאחר ההתחברות נכניס למשתנה את ה-ip
ip- הוא מזהה ייחודי למחשב ברשת שניתן על ידי ספק האינטרנט בעת ההתחברות לאינטרנט, לכן לכל גולש יהיה ip ייחודי משלו שבו נשתמש.
SELECT COUNT(*), UNIX_TIMESTAMP(MAX(`time`))
מהטבלה נשלפים שני נתונים:
א. כמות השורות בה (שעונות לדרישות where)
ב. הרך זמן השליחה המירבי לאותו משתמש (זמן השליחה האחרון)
הזמן נשמר בטבלה בצורת 2010-12-05 12:34:30
אשר אותו מעבירה הפונקציה unix_timestamp לערך מספרי 1288953270
שזוהי כמות השניות שעברה מאז 01/01/1970 עד התאריך הנ"ל.
WHERE `ip`='$ip' AND `time` > DATE_SUB(NOW(), INTERVAL 1 DAY)
את השליפה אנחנו מבצעים רק בעבור השורות שבהם המשתמש הוא המשתמש שהנוכחי (עם אותו ip) ורק בשורות שזמן השליחה שלהם היה ביום האחרון.= זמן שליחה גדול מ(עכשיו פחות יום)
אם יש יותר מ20 שורות שעונות לתנאי - כלומר יותר מ20 שליחות אימייל ביום האחרון - הרי זה ספאם.
אם השליחה האחרונה התבצעה לפני פחות מ60 שניות (לפני פחות מדקה),
גם אז לא ניתן לשולח לשלוח לנו אימייל.
סיכום:
ראינו באופו סכמטי את מהלך בניית טופס יצירת קשר ושליחת אימייל ולא התמקדנו בעיצוב והודעות שגיאות. רצוי מאוד שהטופס שתבנו ידאג לומר למשתמש מה הייתה השגיאה, באיזה שדה, כמה זמן יש לחכות בין שליחת הודעה להודעה ולספר לו על המגבלה של 20 הודעות ביום.
כמו כן צעד נבון יהיה לא להציג למשתמש את הטופס במידה וההודעה נשלחה,
לבקש ממנו אימייל לחזרה אליו ולא לשכוח לבדוק את תיבת הדואר :)
תגובות לכתבה:
שימו לב:
אם משום מה outlook או gmail מציגים לכם את נושא האימייל בג'יבריש או את נושא המייל כסימני שאלה אנא רוא דוגמה לתיקון כאן:
http://phpguide.co.il/forum/index.php/topic,14.0.html
תודה אלכס על העדכון.
<?php
if( isset($_POST['contact'], $_POST['subject'], $_POST['text']) )
{
$subject = trim ($_POST['subject']);
$text = trim ($_POST['text']);
if(strlen($subject) < 3 || strlen($text) < 3) echo 'Text is too short';
}
?>
<form method="post">
Subject: <input type="text" name="subject" value="<?php
if(isset($_POST['subject'])) echo htmlspecialchars($_POST['subject']);
?>"> <br>
Content: <br> <textarea name="text" rows="10" cols="25"><?php
if(isset($_POST['text'])) echo htmlspecialchars($_POST['text']);
?></textarea> <br>
<input type="submit" name="contact" value="Send us a message">
</form>
לא עובד..
הקוד הזה זה רק הקוד של הטופס. הוא לא שולח שום דבר לאף אחד עדיין. השליחה בהמשך. הקוד עצמו הכן עובד (בזכותך נבדק שנית)
אני עשיתי פשוט ככה:
<?php
if (isset($_POST['submit'])) {
$subject =$_POST['subject'];
$text = $_POST['text'];
}
echo <<<Print
<form method="post">
Subject: <input type="text" name="subject" value="<?php
if(isset($_POST['subject'])) echo htmlspecialchars($_POST['subject']);
?>"> <br>
Content: <br> <textarea name="text" rows="10" cols="25"><?php
if(isset($_POST['text'])) echo htmlspecialchars($_POST['text']);
?></textarea> <br>
<input type="submit" name="submit" value="Send us a message">
</form>
Print;
?>
וזה לא עובד..
למה?
מהסיבה שהשתמש ב heredoc
ובתוכו לא יכולים להיות תגי פתיחה, סגירה ותנאים
+ המילה השתמשת בה, Print היא מילה שמורה (פקודה ב PHP)
+ תסתכל איך עובד הפלט בקוד בכתבה ואתה תראה שאין שם echo
אוקי,יש עכשיו עוד בעיה.
אחרי שליחת הטופס,הטופס עדיין מלא,איך מרוקנים אותו?
שאלות בפורום בבקשה.
צריך לדעת html כדי להצליח לנקות את הטופס.
תודה!
אני מעוניין
יש למישהו פתרון לשליחת מייל ב mailer.php משרת ביתי?
אולי זה
http://phpguide.co.il/שליחת אימייל לוקאלי wamp.htm
או זה
http://phpguide.co.il/שליחת_מייל_מ_php_דרך_gmail_smtp.htm
אבל אין סיבה שתתרך. פשוט תעלה את האתר שלך לאחסון כלשהו והכל יהיה בסדר
תודה